<template>
  <div class="palylyric" ref="palylyricEl" :class="{ playing: playing }">
    <div class="mode" v-if="tlyric">
      <span
        :class="{ active: item === lyricMode }"
        v-for="item in lyricModes"
        :key="item"
        @click.stop="lyricMode = item"
        >{{ item }}</span
      >
    </div>

    <section class="content">
      <ul
        ref="listEl"
        :style="{
          marginTop: `-${frontLisHeight}px`,
          transform: `translateY(${palylyricElHeight / 2}px)`,
        }"
      >
        <li
          :class="{ active: currentLyricIndex === index }"
          v-for="(item, index) in currentParsedLyric"
          :key="index"
        >
          <span
            :style="{
              animationDuration: `${
                index === currentParsedLyric.length - 1
                  ? 5
                  : currentParsedLyric[index + 1].time - item.time
              }s`,
            }"
            >{{ item.text || "&nbsp;" }}</span
          >
          <template v-if="item.yw">
            <br />
            <span
              :style="{
                animationDuration: `${
                  index === currentParsedLyric.length - 1
                    ? 5
                    : currentParsedLyric[index + 1].time - item.time - 1
                }s`,
              }"
              >{{ item.yw }}</span
            >
          </template>
        </li>
      </ul>
    </section>
  </div>
</template>

<script>
export default {
  props: ["currentPlaySongId", "currentTime", "playing"],
  data: function () {
    return {
      lyric: "",
      tlyric: "",
      frontLisHeight: 0,
      palylyricElHeight: 0,
      lyricModes: ["原", "译", "双语"],
      lyricMode: "原",
    };
  },
  created: function () {
    this.axios
      .get("https://apis.netstart.cn/music/lyric?id=" + this.currentPlaySongId)
      .then((res) => {
        this.lyric = res.data.lrc.lyric;
        this.tlyric = res.data.tlyric.lyric;
        //
      });
  },
  mounted: function () {
    this.palylyricElHeight = this.$refs.palylyricEl.offsetHeight;
  },
  computed: {
    // 原始
    parsedLyric: function () {
      return this.lyric
        .split("\n")
        .filter((s) => s)
        .map((item) => {
          var match = item.match(
            /^\[(?<time>\d{2}:\d{2}\.\d{2,3})\] *(?<text>.*)$/im
          );

          return match.groups;
        })
        .map((o) => {
          var match = o.time.match(/(?<m>\d{2}):(?<s>\d{2}\.\d{2,3})/i);
          //   console.log(match.groups.m * 60 + match.groups.s * 1);
          return {
            ...o,
            time: (match.groups.m * 60 + match.groups.s * 1).toFixed(3),
          };
        });
    },

    // 翻译
    parsedTLyric: function () {
      return this.tlyric
        .split("\n")
        .filter((s) => s)
        .map((item) => {
          var match = item.match(
            /^(\[(?<time>\d{2}:\d{2}\.\d{2,3})\])? *(?<text>.*)$/im
          );

          return match.groups;
        })
        .filter((o) => o.time)
        .map((o) => {
          var match = o.time.match(/(?<m>\d{2}):(?<s>\d{2}\.\d{2,3})/i);
          //   console.log(match.groups.m * 60 + match.groups.s * 1);
          return {
            ...o,
            time: (match.groups.m * 60 + match.groups.s * 1).toFixed(3),
          };
        });
    },

    // 双语
    parsedSYLyric: function () {
      return this.parsedLyric.map((yso) => {
        var matcho = this.parsedTLyric.find((fyo) => yso.time === fyo.time);
        return matcho ? { ...yso, yw: matcho.text } : yso;
      });
    },

    currentParsedLyric: function () {
      switch (this.lyricMode) {
        case "译":
          return this.parsedTLyric;
        case "双语":
          return this.parsedSYLyric;
        default:
          return this.parsedLyric;
      }
    },
    currentLyricIndex: function () {
      var index = this.currentParsedLyric.findIndex(
        (o) => o.time > this.currentTime
      );
      return index === -1 ? this.currentParsedLyric.length - 1 : index - 1;
    },
  },
  watch: {
    currentLyricIndex: function (n) {
      // console.log(this.parsedLyric[n]);

      // 获取当前高亮行 前面的 所有li
      var frontLis = Array.prototype.slice.call(
        this.$refs.listEl.querySelectorAll("li"),
        0,
        n
        // this.currentLyricIndex
      );

      // 肌酸前面 所有 li的 高度和
      var frontLisHeight = frontLis.reduce(function (total, liEl) {
        return total + liEl.offsetHeight;
      }, 0);
      // console.log(frontLisHeight);
      this.frontLisHeight = frontLisHeight;
    },

    currentPlaySongId: function (n) {
      this.axios
        .get("https://apis.netstart.cn/music/lyric?id=" + n)
        .then((res) => {
          this.lyric = res.data.lrc.lyric;
          this.tlyric = res.data.tlyric.lyric;
          //
        });
    },
  },
};
</script>

<style lang="less" scoped>
@import "../assets/var.less";

@keyframes lyric {
  from {
    background-position-x: 100%;
  }
  to {
    background-position-x: 0%;
  }
}
.palylyric {
  width: 100%;
  height: 100%;
  position: absolute;
  // background: red;
  top: 0;
  left: 0;

  display: flex;
  flex-flow: column;
  .mode {
    // background: red;
    text-align: right;
    span {
      margin: 0 5px;
      &.active {
        color: @red;
      }
    }
  }

  .content {
    overflow: hidden;
    flex: 1;
    mask-image: linear-gradient(
      to bottom,
      transparent 0% 5%,
      red 15% 85%,
      transparent 92% 100%
    );
    color: rgb(214, 214, 214);
    ul {
      text-align: center;
      transition: all 0.5s;

      li {
        line-height: 30px;
        &.active {
          // color: rgb(204, 137, 248);
          span {
            background-image: linear-gradient(
              to right,
              rgb(71, 206, 53) 0% 48%,
              rgb(20, 167, 204) 52% 100%
            );
            font-size: 23px;

            background-size: 200%;
            background-position-x: 100%;
            -webkit-background-clip: text;
            color: transparent;
            animation: lyric 3s linear 0s;
            animation-play-state: paused;
          }
        }
      }
    }
  }

  &.playing {
    ul {
      li {
        &.active {
          span {
            animation-play-state: running;
          }
        }
      }
    }
  }
}
</style>
